package com.zsrd.auth.controller;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zsrd.auth.core.Constants;
import com.zsrd.auth.handle.MySaTokenListener;
import com.zsrd.auth.handle.OnlineUser;
import com.zsrd.auth.utils.PageDtoUtil;
import com.zsrd.core.response.ResponseSupport;
import com.zsrd.auth.core.UserInfoUtil;
import com.zsrd.auth.domain.dto.LoginDto;
import com.zsrd.system.domain.SysDept;
import com.zsrd.system.domain.SysUser;
import com.zsrd.system.service.SysDeptService;
import com.zsrd.system.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <pre>
 *
 * </pre>
 *
 * @author sunjiyong
 * @since 2023/12/8 11:22
 */
@Api(tags = "认证授权")
@RequestMapping("/auth")
@RestController
public class AuthController {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDeptService sysDeptService;

    @PostMapping("/login")
    @ApiOperation(value = "用户登录获取token")
    public ResponseSupport login(@Validated @RequestBody LoginDto loginDto) {
        SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery()
                .eq(SysUser::getUsername, loginDto.getUsername())
                .eq(SysUser::getPassword, SecureUtil.sha256(loginDto.getPassword())));
        if (sysUser == null) {
            return ResponseSupport.fail("用户名或密码不正确");
        }
        if (sysUser.getStatus().intValue() == 0) {
            return ResponseSupport.fail("用户:" + loginDto.getUsername() + "已被禁用");
        }
        StpUtil.login(sysUser.getUserId());
//        // 获取用户的数据权限
//        List<UserDataPower> userDataPowers = sysUserService.getUserDataPowers(sysUser.getUserId());
//        UserInfoAndPowers.UserInfoAndPowersBuilder userInfoAndPowersBuilder = UserInfoAndPowers.builder()
//                .deptId(sysUser.getDeptId())
//                .userId(sysUser.getUserId())
//                .nickName(sysUser.getNickName())
//                .userDataPowers(userDataPowers);
        SysDept dept = sysDeptService.getById(sysUser.getDeptId());
        if (dept != null) {
            sysUser.setDeptName(dept.getDeptName());
        }

        StpUtil.getSession().set(Constants.CURRENT_USER,sysUser);
        return ResponseSupport.success(StpUtil.getTokenInfo());
    }


    @GetMapping("/userInfo")
    @ApiOperation(value = "获取当前用户信息")
    public ResponseSupport userInfo() {
        Map<String, Object> userinfo = UserInfoUtil.userinfo();
        return ResponseSupport.success(userinfo);
    }

    @GetMapping("/userRoles")
    @ApiOperation(value = "获取当前用户包含角色信息")
    public ResponseSupport userRoles() {
        List<String> roleList = UserInfoUtil.getUserRole();
        return ResponseSupport.success(roleList);
    }


    @GetMapping("/loginOut")
    @ApiOperation(value = "登出")
    @SaCheckLogin
    public ResponseSupport loginOut() {
        //获取token
        //   1. 尝试从request里读取 tokenName 默认值 satoken
        //   2. 尝试从请求体里面读取
        //   3. 尝试从header里读取
        //   4. 尝试从cookie里读取
        // 删除cookie
        String loginId=StpUtil.getLoginIdAsString();
        StpUtil.logout();
        return ResponseSupport.success();
    }



    @PostMapping("/onlineUsers")
    @ApiOperation(value = "获取在线用户信息")
//    @SaCheckPermission(value = "super:look",orRole = "admin")//“or校验”：具备指定权限或者指定角色即可通过校验
    public ResponseSupport onlineUsers(@RequestBody LoginDto loginDto) {
        List<String> sessionIds = StpUtil.searchTokenValue(null, -1, 1000,true);
        MySaTokenListener.ONLINE_USERS.sort((o1, o2) -> DateUtil.compare(o2.getLoginTime(), o1.getLoginTime()));
        List<OnlineUser> onlineList=MySaTokenListener.ONLINE_USERS;
        if(StrUtil.isNotBlank(loginDto.getNickName())){
            onlineList=onlineList.stream().filter(u->u.getNickName().indexOf(loginDto.getNickName())>=0).collect(Collectors.toList());
        }
        PageDtoUtil pageDto = PageDtoUtil.getPageDto(onlineList, loginDto.getPageNum(), loginDto.getPageSize());
        List<OnlineUser> pageList = (List<OnlineUser>) pageDto.getRecords();
        pageList.forEach(onlineUser -> {
            String keyLastActivityTime = StpUtil.stpLogic.splicingKeyLastActivityTime(onlineUser.getTokenValue());
            String lastActivityTimeString = SaManager.getSaTokenDao().get(keyLastActivityTime);
            if (lastActivityTimeString != null) {
                long lastActivityTime = Long.parseLong(lastActivityTimeString);
                onlineUser.setLastActivityTime(DateUtil.date(lastActivityTime));
            }
        });
        pageDto.setRecords(pageList);

        return ResponseSupport.success(pageDto);
    }

    @GetMapping("/kickOffline")
    @ApiOperation(value = "踢人下线")
//    @SaCheckPermission(value = "super:operate",orRole = "admin")//“or校验”：具备指定权限或者指定角色即可通过校验
    public ResponseSupport kickOffline(String token) {
        if (StpUtil.getTokenValue().equals(token)) {
            return ResponseSupport.fail("不能踢自己!");
        }
        StpUtil.logoutByTokenValue(token);
        return ResponseSupport.success();
    }


}
